package com.webchat.ugc.messaegqueue.service;


import com.fasterxml.jackson.core.type.TypeReference;
import com.webchat.common.bean.APIResponseBean;
import com.webchat.common.bean.APIResponseBeanUtil;
import com.webchat.common.constants.WebConstant;
import com.webchat.common.enums.mall.im.MallImMessageTypeEnum;
import com.webchat.common.enums.messagequeue.MessageQueueEnum;
import com.webchat.common.service.messagequeue.producer.MessageQueueProducer;
import com.webchat.common.util.DateUtils;
import com.webchat.common.util.IDGenerateUtil;
import com.webchat.common.util.JsonUtil;
import com.webchat.domain.dto.aigc.mall.MallAutoReplayReqDTO;
import com.webchat.domain.vo.dto.mall.im.NettyServerMessageDTO;
import com.webchat.domain.vo.dto.mall.im.UgcServerMessageDTO;
import com.webchat.domain.vo.response.UserBaseResponseInfoVO;
import com.webchat.domain.vo.response.mall.MallShopBaseVO;
import com.webchat.rmi.aigc.AIMallServiceClient;
import com.webchat.ugc.service.AccountService;
import com.webchat.ugc.service.mall.MallShopService;
import com.webchat.ugc.service.mall.im.MallChatAccountService;
import com.webchat.ugc.service.mall.im.MallChatMessageService;
import com.webchat.ugc.service.mall.im.convert.ChatMessageConverter;
import com.webchat.ugc.service.mall.im.convert.MessageConverter;
import freemarker.template.utility.DateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MallIMessageConsumeService {


    @Autowired
    private MessageQueueProducer<UgcServerMessageDTO, Integer> messageQueueProducer;

    @Autowired
    private AccountService accountService;

    @Autowired
    private MallShopService mallShopService;

    @Autowired
    private MallChatMessageService mallChatMessageService;

    @Autowired
    private MallChatAccountService mallChatAccountService;

    @Autowired
    private AIMallServiceClient mallServiceClient;

    @Autowired
    private MallShopService shopService;


    /**
     * 处理来自 NettyServer IM对话消息
     *
     * @param message
     */
    public void doConsumeMessage(String message) {

        UgcServerMessageDTO<Object> ugcServerMessage = transUgcServerMessage(message);
        Integer msgType = ugcServerMessage.getMessageType();
        // 是否需要直接转发的消息类型
        boolean isForwarding = MallImMessageTypeEnum.isForwarding(msgType);
        if (isForwarding) {
            doSendMessageQueue(ugcServerMessage);
            return;
        }
        // 业务逻辑处理（持久化、缓存、红点……）
        this.prePersistentChatMsg(ugcServerMessage);
        // 持久化成功后 需要通知通信流服务完成消息即使推送
        doSendMessageQueue(ugcServerMessage);
        // 发送消息到延迟队列(机器人代发)
        doSendDelayQueueFroAiHandle(ugcServerMessage);
    }

    /**
     * 发送消息到延迟队列，用于后续机器人消息代发（商家在特定时间段内没响应的场景）
     *
     */
    private void doSendDelayQueueFroAiHandle(UgcServerMessageDTO<Object> ugcServerMessage) {

        // 只处理买家消息(ai代理商家回复买家)
        boolean isUserAccount = StringUtils.isBlank(ugcServerMessage.getProxySenderId());
        if (!isUserAccount) {
            return;
        }
        boolean sendOk = messageQueueProducer.prioritySend(MessageQueueEnum.DELAY_QUEUE_MALL_AI_IM_AUTO_MSG,
                                                           ugcServerMessage,
                                                           WebConstant.MALL_AI_IM_MSG_DELAY_TIME);
        if (!sendOk) {
            // 暂时不重新归队处理，这里对正常业务无影响
        }
    }

    private void prePersistentChatMsg(UgcServerMessageDTO<?> ugcServerMessage) {
        // 1. 持久化对话列表
        mallChatAccountService.add(ugcServerMessage.getSenderId(),
                                   ugcServerMessage.getReceiverId(),
                                   ugcServerMessage.getMsgTime());
        // 2. 持久化IM消息
        mallChatMessageService.add(ugcServerMessage);
    }

    private UgcServerMessageDTO transUgcServerMessage(String message) {
        NettyServerMessageDTO<Object> nettyServerMessage =
                JsonUtil.fromJson(message, new TypeReference<NettyServerMessageDTO<Object>>() { });
        UgcServerMessageDTO<Object> ugcServerMessage = new UgcServerMessageDTO<>();
        BeanUtils.copyProperties(nettyServerMessage, ugcServerMessage);
        /**
         * 设置消息代理人
         */
        String senderId = ugcServerMessage.getSenderId();
        String receiverId = ugcServerMessage.getReceiverId();

        Long shopId = mallShopService.getManageShopId(senderId);
        if (shopId != null) {
            ugcServerMessage.setProxySenderId(senderId);
            ugcServerMessage.setSenderId(String.valueOf(shopId));
        }
        boolean isUserAccount = accountService.isUserAccount(receiverId);
        if (!isUserAccount) {
            // 是否商家
            String proxyUserId = mallShopService.getShopManager(Long.valueOf(receiverId));
            ugcServerMessage.setProxyReceiverId(proxyUserId);
        }
        return ugcServerMessage;
    }

    private void doSendMessageQueue(UgcServerMessageDTO message) {
        try {
            messageQueueProducer.send(MessageQueueEnum.UGC_TO_NETTY_MESSAGE, message);
        } catch (Exception e) {

            // TODO 队列入队异常处理

        }

    }

    /**
     * 消费客服系统延迟队列消息（用于机器人消息代发）
     *
     * @param message
     */
    public void doConsumeDelayQueueMessageForAutoReplay(String message) {

        UgcServerMessageDTO<Object> ugcServerMessage = transUgcServerMessage(message);

        // 1. 获取消息时间
        Long msgTime = ugcServerMessage.getMsgTime();
        // 2. 校验当前消息时间之后有没有商家消息（有，则认为商家是有响应的，无需代发）
        List<UgcServerMessageDTO> messages = mallChatMessageService.listOrderBySendTimeAsc(
                ugcServerMessage.getSenderId(),
                ugcServerMessage.getReceiverId(),
                msgTime,
                DateUtils.getCurrentTimeMillis());
        // 筛选商家回复消息
        List<UgcServerMessageDTO> shopMessages = messages.stream().filter(msg ->
                StringUtils.isNotBlank(msg.getProxySenderId())).toList();
        if (CollectionUtils.isNotEmpty(shopMessages)) {
            // 有店铺消息回复，不需要机器人代发
            return;
        }
        // 3. 需要代发
        // 3.1 获取当前这个消息之后的所有买家消息
        List<UgcServerMessageDTO> userMessages = messages.stream().filter(msg ->
                StringUtils.isBlank(msg.getProxySenderId())).toList();
        List<String> userMessageArr = userMessages.stream().map(ChatMessageConverter::text).toList();

        // 获取买家信息
        UserBaseResponseInfoVO user = accountService.accountInfo(ugcServerMessage.getSenderId());
        // 获取店铺信息
        MallShopBaseVO shop = shopService.shopInfo(Long.valueOf(ugcServerMessage.getReceiverId()));

        // 3.2 UGC prompt template渲染电商客服业务场景的来自买家问题Prompt
        // 3.2 RPC 请求 webchat-aigc ai生成回复
        MallAutoReplayReqDTO mallAutoReplayReq = new MallAutoReplayReqDTO();
        mallAutoReplayReq.setUsername(user.getUserName());
        mallAutoReplayReq.setShopName(shop.getName());
        mallAutoReplayReq.setUserMessages(userMessageArr);
        APIResponseBean<String> apiResponseBean = mallServiceClient.aiAutoReply(mallAutoReplayReq);
        if (!APIResponseBeanUtil.isOk(apiResponseBean)) {
            // AI 客服消息生成RPC调用失败，暂时不做处理
            // TODO 如果想要处理处理，可以重新归队
            return;
        }
        String aiReplyMessage = apiResponseBean.getData();
        // 4. 持久化ai代发消息（redis + mondoDb）
        UgcServerMessageDTO<String> aiAutoReplyMessage = buildAiAutoReplyMessage(ugcServerMessage, aiReplyMessage);
        prePersistentChatMsg(aiAutoReplyMessage);
        // 5. 消息发送（通信流通道发送消息）
        // 走MQ下发消息到通信流server，由Netty Server集群将消息push到买家客户端
        doSendMessageQueue(aiAutoReplyMessage);
    }

    /**
     * 构造Ai生成的内容
     *
     * @param ugcServerMessage
     * @param aiGenerateMessage
     * @return
     */
    private UgcServerMessageDTO<String> buildAiAutoReplyMessage(UgcServerMessageDTO<Object> ugcServerMessage,
                                                                String aiGenerateMessage) {
        UgcServerMessageDTO<String> aiAutoReplyMessage = new UgcServerMessageDTO<>();
        // 最新消息发送人对应原消息接收人（商家）
        aiAutoReplyMessage.setSenderId(ugcServerMessage.getReceiverId());
        // ai代发消息的接收人对应原消息发送人（买家）
        aiAutoReplyMessage.setReceiverId(ugcServerMessage.getSenderId());
        aiAutoReplyMessage.setAiGenerate(true);
        aiAutoReplyMessage.setMsgTime(DateUtils.getCurrentTimeMillis());
        aiAutoReplyMessage.setMsgId(IDGenerateUtil.createId("IM"));
        aiAutoReplyMessage.setMessage(aiGenerateMessage);
        aiAutoReplyMessage.setRead(false);
        aiAutoReplyMessage.setMessageType(MallImMessageTypeEnum.MSG_TEXT.getTypeCode());
        return aiAutoReplyMessage;
    }

    /**
     * ai 代发
     *
     * @return
     */
    private String aiGenerateReply() {

        return null;
    }

    private boolean hasShopMessageWithDelayQueueConsume(UgcServerMessageDTO<Object> ugcServerMessage ) {
        Long msgTime = ugcServerMessage.getMsgTime();
        List<UgcServerMessageDTO> messages = mallChatMessageService.listOrderBySendTimeAsc(
                ugcServerMessage.getSenderId(),
                ugcServerMessage.getReceiverId(),
                msgTime,
                DateUtils.getCurrentTimeMillis());
        if (CollectionUtils.isEmpty(messages)) {
            return true;
        }
        List<UgcServerMessageDTO> shopMessages = messages.stream().filter(msg ->
                StringUtils.isNotBlank(msg.getProxySenderId())).toList();
        // 有店铺消息回复，不需要机器人代发
        return CollectionUtils.isNotEmpty(shopMessages);
    }
}
